<template>
    <div>
        <div >
            <div className="modal-overlay" />
            <div style="background-color: beige">
                <el-row type="flex">
                    <el-col :span="6">
                        <span class="demonstration">字体颜色</span>
                        <el-color-picker v-model="color" :change="colorChange"></el-color-picker>
                    </el-col>
                    <el-col :span="6">
                        <span class="demonstration">背景颜色</span>
                        <el-color-picker v-model="bgColor"  :change="bgColorChange"></el-color-picker>
                    </el-col>
                    <el-col :span="6">
                        <el-input v-model="delay" ><template slot="prepend">动图延迟：</template></el-input>
                    </el-col>
                    <el-col :span="6">
                        <el-button @click="savePic">保存图片</el-button>
                    </el-col>
                </el-row>
            </div>

            <div className="modal-box">
                <div className="output-text-wrapper">
                    <div id="output-text-block" class="output-text-block" v-html="outputText"  :style="{color:color,backgroundColor:bgColor}">
                    </div>
                </div>
            </div>
        </div>
    </div>
    
</template>

<style>
    .output-text-wrapper {
        padding: 20px;
    }
    .output-text-block {
        max-height: calc(100vh - 200px);
        max-width: 90vw;
        width: max-content;
        margin: 0 auto;
        font-size: 12px;
        line-height: 12px;
        border: 1px solid #333;
        overflow: auto;
    }
    .output-text-block pre {
        margin: 0;
        padding: 0;
    }
</style>

<script>
    import GIF from 'gif.js';
    const FONT_WIDTH = 6
    const FONT_HEIGHT = 12
    const TEXT_FONT = `normal normal 400 normal ${FONT_HEIGHT}px / ${FONT_HEIGHT}px monospace, monospace`
    const IMAGE_TYPES_RE = {
        PNG: /image\/png/,
        JPG: /image\/jpe?g/,
        GIF: /image\/gif/,
    }
    const COLOR = {
        BLACK: 'rgba(0,0,0,1)',
        WHITE: 'rgba(255,255,255,1)'
    }
    const DEFAULT_GIF_PROPS = {
        bgColor: COLOR.WHITE,
        color: COLOR.BLACK,
        font: TEXT_FONT
    }

    const DEFAULT_NOGIF_PROPS = {
        bgColor: COLOR.WHITE,
        color: COLOR.BLACK,
        font: TEXT_FONT
    }
    export default {
        name: "frames-modal",
        props: {
            file:'',
            frames:''
        },
        data() {
            return {
                frameIndex: 0,
                playTimer: undefined,
                color:'#000000',
                bgColor:'#ffffff',
                color_1:'#000000',
                bgColor_1:'#ffffff',
                delay:1,
            };
        },
        created() {

        },
        destroyed(){
            this.clearTimeout();
        },
        methods: {
            colorChange(val){
                console.log('colorChange',val);
                this.color =   val;
            },
            bgColorChange(val){
                console.log('bgColorChange',val);
                this.bgColor =   val;
            },
            clearTimeout(){
                if (this.playTimer){
                    clearTimeout(this.playTimer);
                }
            },
            nextFrame(){
                this.clearTimeout();
                if (Array.isArray(this.frames)){
                    this.playTimer = setTimeout(()=>{
                        if (Array.isArray(this.frames)){
                            if (this.frameIndex < this.frames.length -1){
                                this.frameIndex ++;
                            }else{
                                this.frameIndex = 0;
                            }
                        }
                    },this.frames[this.frameIndex].delay * (this.delay||1))
                }
            },
            savePic(){
                const createOption = {
                    div: document.getElementById('output-text-block'),
                    frames: this.frames,
                    file: this.file,
                    color: this.color,
                    bgColor: this.bgColor
                }
                this.createImage(createOption);
            },
            getImageType(type) {
                for (const typeName in IMAGE_TYPES_RE) {
                    const typeRe = IMAGE_TYPES_RE[typeName]
                    if (typeRe.test(type)) {
                        return typeName
                    }
                }
            },
            createImage(option) {
                const { div, frames, file, ...props } = option
                const type = this.getImageType(file.type)

                const link = document.createElement('a')
                let filename = file.name.split('.')
                filename[filename.length - 2] = filename[filename.length - 2] + '-text'
                filename = filename.join('.')
                link.download = filename

                if (type === 'GIF') {
                    this.gif(div, frames, props, function(blob) {
                        const url = URL.createObjectURL(blob)
                        link.href = url
                        link.click()
                        URL.revokeObjectURL(url)
                    })
                } else {
                    link.href = this.noGif(div, frames[0], props)
                    link.click()
                }
            },
            gif(div, frames, props, cb) {
                props = Object.assign({}, DEFAULT_GIF_PROPS, props)
                const width = div.scrollWidth
                const height = div.scrollHeight
                const gif = new GIF({
                    quality: 10,
                    workers: 2,
                    workerScript:process.env.VUE_APP_GIF_WORKER_PATH,
                    width,
                    height
                })
                gif.on('finished', function(blob) {
                    cb(blob)
                })
                for (let i = 0; i < frames.length; i++) {
                    const canvas = this.getFrameCanvas(div, frames[i].text, props)
                    gif.addFrame(canvas, {
                        delay: frames[i].delay * (this.delay||1)
                    })
                }
                gif.render()
            },
            noGif(div, frame, props) {
                props = Object.assign({}, DEFAULT_NOGIF_PROPS, props)
                const canvas = this.getFrameCanvas(div, frame.text, props)
                return canvas.toDataURL('image/png')
            },
            getFrameCanvas(div, frame, props) {
                const canvas = document.createElement('canvas')
                canvas.width = div.scrollWidth
                canvas.height = div.scrollHeight
                const ctx = canvas.getContext('2d')
                ctx.fillStyle = props.bgColor
                ctx.fillRect(0, 0, canvas.width, canvas.height)
                ctx.fillStyle = props.color
                ctx.font = props.font
                for (let i = 0; i < frame.length; i++) {
                    for (let j = 0; j < frame[i].length; j++) {
                        ctx.fillText(frame[i][j], j * FONT_WIDTH, i * FONT_HEIGHT)
                    }
                }
                return canvas
            }
        },
        computed:{
            outputText(){
                let htmlArray = this.frames.length
                    ? this.frames[this.frameIndex].text.map((line, index) => { return "<pre key='"+index+"'>"+line+"</pre>" })
                    : null;
                let str = ''
                Array.isArray(htmlArray)&& htmlArray.forEach(bean=>{
                    str += bean;
                })
                this.nextFrame();
                return str
            }
        }
    }
</script>

<style scoped>

</style>